import time

import DXFServer
import dnf_skill_recognition
import random
import keyboard


class GamePathPlanner:
    def __init__(self):
        """初始化游戏路径规划器"""
        self.hwnd = None
        self.i_room = None
        self.boss_room = None
        self.map_type = None
        self.map_position = None
        self.win_left = None
        self.win_top = None
        # 身高
        self.rise = None
        # 速度
        self.speed = None
        # 停顿时长
        self.ts = 0.35
        # 日志函数
        self.log_function = None
        # 黑屏次数
        self.back_count = 10

        # 模板缓存初始化（仅记录有效模板路径）
        self.valid_templates = set()

        self.mini_map_templates = None
        self.mini_map_temp_types = None

    def set_log_function(self, log_func):
        """设置日志函数"""
        self.log_function = log_func
        return self

    def log(self, message, level="INFO"):
        """输出日志"""
        if self.log_function:
            self.log_function(message, level)
        else:
            print(message)  # 如果没有设置日志函数，使用print作为后备

    def set_boss_position(self, b_position):
        """设置BOSS房间位置"""
        self.boss_room = b_position
        return self

    def set_i_position(self, i_position):
        """设置当前小人房间位置"""
        self.i_room = i_position
        return self

    def set_hwnd(self, hwnd):
        """设置游戏窗口句柄"""
        self.hwnd = hwnd
        return self

    def set_map_data(self, map_data_type):
        """设置地图数据"""
        self.map_type = map_data_type.get('name')
        self.map_position = map_data_type.get('position')
        return self

    def plan_path(self):
        """执行路径规划"""
        if not self.map_type or self.map_position is None or self.boss_room is None:
            raise ValueError("请先设置地图数据和BOSS位置")

        # 根据地图类型选择对应的路径规划方法
        if self.map_type == '引擎':
            return self._plan_engine_path()
        elif self.map_type == '森林':
            return self._plan_forest_path()
        elif self.map_type == '群岛':
            return self._plan_islands_path()
        else:
            return self._handle_unknown_map()

    def _plan_engine_path(self):
        """引擎地图路径规划"""
        if self.map_position == (4, 1):
            return self._handle_engine_4_1()
        elif self.map_position == (5, 2):
            return self._handle_engine_5_2()
        elif self.map_position == (6, 1) and self.boss_room == (6, 2):
            return self._handle_engine_6_1_boss_6_2()
        else:
            return self._handle_engine_default()

    def _plan_forest_path(self):
        """森林地图路径规划"""
        if self.map_position == (2, 1):
            return self._handle_forest_2_1()
        elif self.map_position == (4, 0):
            return self._handle_forest_4_0()
        elif self.map_position == (4, 1) and self.boss_room == (6, 0):
            return self._handle_forest_4_1_boss_6_0()
        else:
            return self._handle_forest_default()

    def _plan_islands_path(self):
        """群岛地图路径规划"""
        if self.map_position == (2, 1):
            return self._handle_islands_2_1()
        elif self.map_position == (3, 0):  # 验证
            return self._handle_islands_3_0()
        elif self.map_position == (3, 1):
            return self._handle_islands_3_1()
        else:
            return self._handle_islands_default()

    # 以下是各种具体情况的处理方法，目前为空实现
    # 你可以根据实际需求填充这些方法的具体逻辑

    # 人工调整【完成】
    def _handle_engine_4_1(self):
        self.log(f"【引擎地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (0, 1):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (1, 1):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 500, 368, img); distance_2 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (2, 1):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 500, 368, img); distance_3 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (3, 1):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 662, 388, img); distance_4 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (4, 1):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 652, 448, img); distance_5 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 552, 366, img); distance_6 = False
                handle_right_up_room_logic(self, 820, 159, i_position, door_num=True, door_y=370)
            elif i_position == (5, 0):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 436, 363, img,
                                                      skill_direction=keyboard.Left); distance_7 = False
                get_player_position_up_move(self, y_height=460, t_ms=0.3)
                handle_left_down_room_logic(self, 0, 0, i_position, door_y=500, door_x=530)
            elif i_position == (6, 0):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 588, 438, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "引擎地图(4,1)路径规划 【👹】")
            else:
                self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "引擎地图(4,1)路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    def _handle_engine_5_2(self):
        # self.log(f"【引擎地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (3, 2):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (4, 2):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 700, 440, img); distance_2 = False
                get_player_position_up_move(self, 460)
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 2):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 640, 385, img); distance_3 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (6, 2):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 700, 350, img); distance_4 = False
                handle_right_up_room_logic(self, 1425, 121, i_position, door_num=True, door_x=100)
            elif i_position == (6, 1):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 530, 320, img,
                                                      skill_direction=keyboard.Left); distance_5 = False
                get_player_position_up_move(self, 440)
                handle_right_up_room_logic(self, 0, 0, i_position, door_num=False, door_x=122)
            elif i_position == (5, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 98, 498, img); distance_6 = False
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                get_player_position_down_move_right(self, 480)
                handle_left_up_room_logic(self, 890, 113, i_position, door_y=314, target_out=430)
            elif i_position == (5, 0):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 681, 339, img,
                                                      skill_direction=keyboard.Left); distance_7 = False
                handle_left_room_logic(self, i_position, 310, 330)
            elif i_position == (4, 0):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 160, 454, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "引擎地图(5,2)路径规划 【👹】")
            else:
                self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "引擎地图(5,2)路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    def _handle_engine_6_1_boss_6_2(self):
        self.log(f"【引擎地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (5, 0):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (6, 0):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 523, 380, img); distance_2 = False
                get_player_position_up_move(self, 487)
                handle_right_down_room_logic(self, 784, 243, i_position, mini_ht=540)
            elif i_position == (6, 1):  # 第三个房间 有卡槽
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 625, 360, img,
                                                      skill_direction=keyboard.Left); distance_3 = False
                get_player_position_right_move(self, 420, 418, 380)
                handle_right_up_room_logic2(self, 0, 0, i_position, 380, 280)
            elif i_position == (5, 1):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 356, 384, img); distance_4 = False
                handle_left_room_logic(self, i_position)
            elif i_position == (4, 1):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 375, 363, img); distance_5 = False
                handle_left_down_room_logic(self, 423, 210, i_position, 500)
            elif i_position == (4, 2):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 300, 493, img,
                                                      skill_direction=keyboard.Right); distance_6 = False
                get_player_position_up_move(self, y_height=400, top_height=344)
                handle_left_up_room_logic(self, 0, 0, i_position, door_y=350)
            elif i_position == (5, 2):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 570, 453, img); distance_7 = False
                handle_right_room_logic(self, i_position, door_len=600)
            elif i_position == (6, 2):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 680, 410, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "引擎地图(6,1)且BOSS在(6,2)的路径规划 【👹】")
            else:
                self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "引擎地图(6,1)且BOSS在(6,2)的路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    def _handle_engine_default(self):
        self.log(f"【引擎地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (3, 0):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (4, 0):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 520, 350, img); distance_2 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 0):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 560, 369, img); distance_3 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (6, 0):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 716, 363, img); distance_4 = False
                get_player_position_up_move(self, 500)
                handle_right_down_room_logic(self, 753, 258, i_position, mini_wd=100, mini_ht=492)
            elif i_position == (6, 1):  # 第五个房间 351
                self.log("🏰 进入第五个房间")
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                if distance_5: hero_room_position_one(self, data, 600, 383, img,
                                                      skill_direction=keyboard.Left); distance_5 = False
                get_player_position_right_move(self, x_wd=412, w_ht=440, top_height=343)
                handle_right_up_room_logic(self, 0, 0, i_position, door_num=False)
            elif i_position == (5, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 50, 482, img); distance_6 = False
                get_player_position_down_move_left(self, 437)
                handle_left_room_logic(self, i_position)
            elif i_position == (4, 1):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 448, 362, img); distance_7 = False
                handle_left_room_logic(self, i_position, 300, 300)
            elif i_position == (3, 1):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 588, 438, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "引擎地图默认路径规划 【👹】")
            else:
                self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "引擎地图默认路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    def _handle_forest_2_1(self):
        self.log(f"【森林地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (0, 1):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (1, 1):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 450, 388, img); distance_2 = False
                get_player_position_down_move_left(self, 400)
                handle_right_room_logic(self, i_position)
            elif i_position == (2, 1):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 511, 363, img); distance_3 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (3, 1):  # 第四个房间  【解决找门误判】
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 718, 517, img); distance_4 = False
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                get_player_position_down_move_left(self, 400)
                # 纵轴小于380是出口门
                handle_right_up_room_logic(self, 540, 157, i_position, door_num=True, door_x=80, door_y=380)
            elif i_position == (3, 0):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 593, 347, img,
                                                      skill_direction=keyboard.Left); distance_5 = False
                get_player_position_up_move(self, y_height=460, t_ms=0.3)
                handle_left_down_room_logic(self, 0, 0, i_position, 500)
            elif i_position == (4, 0):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 531, 405, img); distance_6 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 0):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 603, 443, img); distance_7 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (6, 0):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 794, 446, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "森林地图(2,1)路径规划 【👹】")
            else:
                self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "森林地图(2,1)路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    def _handle_forest_4_0(self):
        self.log(f"【森林地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (0, 1):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (1, 1):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 434, 466, img); distance_2 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (2, 1):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 483, 478, img); distance_3 = False
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                get_player_position_down_move_left(self, 390)
                handle_right_up_room_logic(self, 600, 160, i_position, door_num=True, door_x=100)
            elif i_position == (2, 0):  # 第四个房间t
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 778, 385, img,
                                                      skill_direction=keyboard.Left); distance_4 = False
                get_player_position_up_move(self, y_height=540, t_ms=0.3)
                handle_left_down_room_logic(self, 0, 0, i_position, door_y=None, door_x=703)
            elif i_position == (3, 0):  # 第五个房间【模型识别该房间困难】
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 735, 384, img); distance_5 = False
                get_player_position_down_move_left(self, 424)
                handle_right_room_logic(self, i_position)
            elif i_position == (4, 0):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 529, 452, img); distance_6 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 0):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 447, 450, img); distance_7 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (6, 0):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 784, 453, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "森林地图(4,0)路径规划 【👹】")
            else:
                self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "森林地图(4,0)路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    def _handle_forest_4_1_boss_6_0(self):
        self.log(f"【森林地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (1, 0):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (2, 0):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 610, 352, img); distance_2 = False
                handle_right_down_room_logic(self, 915, 153, i_position, mini_wd=100, mini_ht=540)
            elif i_position == (2, 1):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 94, 483, img,
                                                      skill_direction=keyboard.Right); distance_3 = False
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                get_player_position_down_move_right(self, 401)
                handle_left_up_room_logic(self, 0, 0, i_position, door_y=400)
            elif i_position == (3, 1):  # 第四个房间   怪物识别有问题
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 741, 423, img); distance_4 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (4, 1):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 524, 468, img); distance_5 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 518, 420, img); distance_6 = False
                get_player_position_down_move_left(self, 400)
                handle_right_up_room_logic(self, 620, 135, i_position, door_num=True)
            elif i_position == (5, 0):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 707, 367, img,
                                                      skill_direction=keyboard.Left); distance_7 = False
                get_player_position_up_move(self, y_height=460, t_ms=0.3)
                handle_left_down_room_logic(self, 0, 0, i_position, 600)
            elif i_position == (6, 0):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 750, 375, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "森林地图(4,1)且BOSS在(6,0)的路径规划 【👹】")
            else:
                self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "森林地图(4,1)且BOSS在(6,0)的路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    def _handle_forest_default(self):
        self.log(f"【森林地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (1, 1):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (2, 1):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 390, 478, img); distance_2 = False
                get_player_position_down_move_left(self, 394)
                handle_right_up_room_logic(self, 892, 160, i_position, door_num=True)
            elif i_position == (2, 0):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 426, 453, img,
                                                      skill_direction=keyboard.Left); distance_3 = False
                get_player_position_up_move(self, y_height=460, t_ms=0.3)
                handle_left_down_room_logic(self, 0, 0, i_position, 540)
            elif i_position == (3, 0):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 358, 494, img); distance_4 = False
                get_player_position_down_move_left(self, 412)
                handle_right_room_logic(self, i_position)
            elif i_position == (4, 0):  # 第五个房间 ？ 未识别
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 650, 552, img); distance_5 = False
                # 满足入口门小于100 出口门纵轴一定会大于 500 直接进
                handle_right_down_room_logic(self, 770, 334, i_position, mini_ht=500)
            elif i_position == (4, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 390, 557, img,
                                                      skill_direction=keyboard.Right); distance_6 = False
                # 找偏移【右边门有时候在最下面、如果一直右走是找不到出口的。】
                handle_right_down_room_logic(self, 597, 290, i_position, mini_wd=737)
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 1):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 520, 469, img); distance_7 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (6, 1):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 509, 437, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "森林地图默认路径规划 【👹】")
            else:
                # self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                if count > self.back_count and brand_shown(self):
                    # self.log(f"黑屏进入boss房间通道通道时刻！")
                    agan_shown(self)
                    return "森林地图默认路径规划 【👹】注：黑屏通道。"
                count += 1
            time.sleep(self.ts)

    # 人工调整【完成】归元 修复
    def _handle_islands_2_1(self):
        # self.log(f"【群岛地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (1, 1):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (2, 1):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 664, 352, img); distance_2 = False
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                get_player_position_up_move(self, 350)
                handle_right_room_logic(self, i_position)
            elif i_position == (3, 1):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 645, 345, img); distance_3 = False
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                get_player_position_up_move(self, 400, 352)  # 已修复
                handle_right_room_logic(self, i_position)
            elif i_position == (4, 1):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 778, 427, img); distance_4 = False
                get_player_position_down_move_left(self, 390)
                handle_right_up_room_logic2(self, 375, 175, i_position, 435)
            elif i_position == (4, 0):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 660, 320, img,
                                                      skill_direction=keyboard.Left); distance_5 = False
                handle_left_up_room_logic(self, 0, 0, i_position, door_y=320, target_x=677)
            elif i_position == (5, 0):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 631, 387, img); distance_6 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (6, 0):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 517, 421, img); distance_7 = False
                get_player_position_up_move(self, y_height=400, top_height=370)  # 已修复
                handle_right_down_room_logic(self, 580, 290, i_position)
            elif i_position == (6, 1):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 457, 462, press_key=keyboard.Alt)
                get_player_position_down_move_left(self, 370)
                return get_boos_room_status(self, i_position, "群岛地图(2,1)路径规划 【👹】")
            else:
                b_found, _ = get_found_position(minimaps, 'b.png')
                # 如果boss房间存在 说明进入特殊房间，直接找怪打就行
                if b_found:
                    if distance_2: hero_room_position_one(self, data, 664, 352, img); distance_2 = False
                    # 检查玩家纵轴坐标是否大于450 避免归元卡图
                    get_player_position_up_move(self, 350)
                    handle_right_room_logic(self, i_position)
                else:
                    self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                    if count > self.back_count and brand_shown(self):
                        self.log(f"黑屏进入boss房间通道通道时刻！")
                        agan_shown(self)
                        return "群岛地图(2,1)路径规划 【👹】注：黑屏通道。"
                    count += 1
            time.sleep(self.ts)

    # 人工调整【完成】归元
    def _handle_islands_3_0(self):
        self.log(f"【群岛地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (1, 0):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (2, 0):  # 第二个房间
                self.log("🏰 进入第二个房间")
                # 检查玩家纵轴坐标是否大于450 避免归元卡图
                if distance_2: hero_room_position_one(self, data, 598, 380, img); distance_2 = False
                get_player_position_up_move(self, 350, t_ms=0.3)
                handle_right_room_logic(self, i_position)
            elif i_position == (3, 0):  # 第三个房间
                self.log("🏰 进入第三个房间")
                # 检查玩家纵轴坐标是否大于400 避免归元卡图
                if distance_3: hero_room_position_one(self, data, 614, 423, img); distance_3 = False
                get_player_position_up_move(self, 352, 362)
                handle_right_room_logic(self, i_position)
            elif i_position == (4, 0):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 789, 418, img); distance_4 = False
                get_player_position_up_move(self, 500, t_ms=0.3)
                handle_right_down_room_logic(self, 616, 213, i_position, mini_wd=100, mini_ht=500)
            elif i_position == (4, 1):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 510, 435, img); distance_5 = False
                get_player_position_up_move(self, 460, t_ms=0.3)
                handle_left_up_room_logic(self, 0, 0, i_position, door_y=356, target_x=676)
            elif i_position == (5, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 643, 411, img); distance_6 = False
                get_player_position_down_move_left(self, 400)
                handle_right_room_logic(self, i_position)
            elif i_position == (6, 1):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 557, 470, img); distance_7 = False
                get_player_position_down_move_left(self, 396)
                handle_right_up_room_logic(self, 761, 60, i_position, door_num=True, door_x=100)
            elif i_position == (6, 0):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 503, 379, press_key=keyboard.Alt, skill_direction=keyboard.Left)
                return get_boos_room_status(self, i_position, "群岛地图(3,0)路径规划 【👹】")
            else:
                # 如果boss房间存在 说明进入特殊房间，直接找怪打就行
                b_found, _ = get_found_position(minimaps, 'b.png')
                if b_found:
                    if distance_3: hero_room_position_one(self, data, 614, 423, img); distance_3 = False
                    get_player_position_up_move(self, 352, 362)
                    handle_right_room_logic(self, i_position)
                else:
                    self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                    if count > self.back_count and brand_shown(self):
                        self.log(f"黑屏进入boss房间通道通道时刻！")
                        agan_shown(self)
                        return "群岛地图(3,0)路径规划 【👹】注：黑屏通道。"
                    count += 1
            time.sleep(self.ts)

    # 人工调整【完成】归元 修复
    def _handle_islands_3_1(self):
        # self.log(f"【群岛地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (1, 0):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (2, 0):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 650, 312, img); distance_2 = False
                # 检查玩家纵轴坐标是否大于400 避免归元卡图
                get_player_position_up_move(self, 350)
                handle_right_room_logic(self, i_position)
            elif i_position == (3, 0):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 575, 380, img); distance_3 = False
                # 检查玩家纵轴坐标是否大于400 避免归元卡图
                get_player_position_up_move(self, 350, 350)
                handle_right_down_room_logic(self, 953, 236, i_position, mini_wd=100, mini_ht=530)  # 入口门x<100 出口门Y>530
            elif i_position == (3, 1):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 299, 459, img,
                                                      skill_direction=keyboard.Left); distance_4 = False
                get_player_position_up_move(self, 480, t_ms=0.35)
                handle_left_up_room_logic(self, 0, 0, i_position, door_y=360)
            elif i_position == (4, 1):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 756, 472, img); distance_5 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 611, 393, img); distance_6 = False
                # 检查玩家纵轴坐标是否大于400 避免归元卡图
                get_player_position_up_move(self, 480, t_ms=0.5)
                handle_right_down_room_logic(self, 365, 200, i_position)
            elif i_position == (5, 2):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 606, 428, img,
                                                      skill_direction=keyboard.Left); distance_7 = False
                get_player_position_up_move(self, y_height=350, top_height=347)  # 优先判断是否需要上下移
                handle_left_up_room_logic(self, 0, 0, i_position, door_y=365)
            elif i_position == (6, 2):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 688, 350, press_key=keyboard.Alt)
                return get_boos_room_status(self, i_position, "群岛地图(3,1)路径规划 【👹】")
            else:
                b_found, _ = get_found_position(minimaps, 'b.png')
                if b_found:
                    if distance_4: hero_room_position_one(self, data, 299, 459, img,
                                                          skill_direction=keyboard.Left); distance_4 = False
                    handle_left_up_room_logic(self, 0, 0, i_position, door_y=360)
                else:
                    self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                    if count > self.back_count and brand_shown(self):
                        self.log(f"黑屏进入boss房间通道通道时刻！")
                        agan_shown(self)
                        return "群岛地图(3,1)路径规划 【👹】注：黑屏通道。"
                    count += 1
            time.sleep(self.ts)

    # 人工调整【完成】归元
    def _handle_islands_default(self):
        self.log(f"【群岛地图】：【{self.i_room}】 特殊标记：【{self.map_position}】 boos标记：{self.boss_room}")
        distance_2, distance_3, distance_4, distance_5, distance_6, distance_7, distance_8 = True, True, True, True, True, True, True
        count = 0  # 计数器初始值
        while True:
            minimaps, img = DXFServer.get_mini_map(self)
            i_position = DXFServer.get_current_root_index(minimaps)
            data = DXFServer.get_image_info(img)
            print(f"小地图信息检测:{minimaps} ===== 位置：{i_position}")
            if i_position == (1, 0):  # 第一个房间
                self.log("🏰 进入第一个房间，开始找门")
                handle_first_room_logic(self, i_position)
            elif i_position == (2, 0):  # 第二个房间
                self.log("🏰 进入第二个房间")
                if distance_2: hero_room_position_one(self, data, 611, 328, img); distance_2 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (3, 0):  # 第三个房间
                self.log("🏰 进入第三个房间")
                if distance_3: hero_room_position_one(self, data, 611, 339, img); distance_3 = False
                get_player_position_down_move_right(self, 370)
                handle_right_room_logic(self, i_position)
            elif i_position == (4, 0):  # 第四个房间
                self.log("🏰 进入第四个房间")
                if distance_4: hero_room_position_one(self, data, 759, 460, img); distance_4 = False
                handle_right_room_logic(self, i_position)
            elif i_position == (5, 0):  # 第五个房间
                self.log("🏰 进入第五个房间")
                if distance_5: hero_room_position_one(self, data, 630, 394, img); distance_5 = False
                # 检查玩家纵轴坐标是否大于400 避免归元卡图
                get_player_position_up_move(self, 350)
                handle_right_down_room_logic(self, 1130, 247, i_position)
            elif i_position == (5, 1):  # 第六个房间
                self.log("🏰 进入第六个房间")
                if distance_6: hero_room_position_one(self, data, 635, 400, img); distance_6 = False
                # 检查玩家纵轴坐标是否大于400 避免归元卡图
                get_player_position_up_move(self, 350)
                handle_left_up_room_logic(self, 0, 0, i_position, door_y=380)
            elif i_position == (6, 1):  # 第七个房间
                self.log("🏰 进入第七个房间")
                if distance_7: hero_room_position_one(self, data, 580, 278, img); distance_7 = False
                handle_right_up_room_logic(self, 495, 126, i_position, door_num=False)
            elif i_position == (6, 0):  # BOSS 房间
                self.log("🏰 进入BOSS 房间")
                hero_room_position_one(self, data, 463, 374, press_key=keyboard.Alt, skill_direction=keyboard.Left)
                return get_boos_room_status(self, i_position, "群岛地图默认路径规划 【👹】")
            else:
                # 如果boss房间存在 说明进入特殊房间，直接找怪打就行
                b_found, _ = get_found_position(minimaps, 'b.png')
                if b_found:
                    if distance_6: hero_room_position_one(self, data, 635, 400, img); distance_6 = False
                    handle_left_up_room_logic(self, 0, 0, i_position, door_y=380)
                else:
                    self.log(f"这是第{count + 1} 次循环、黑屏时刻！")
                    if count > self.back_count and brand_shown(self):
                        self.log(f"黑屏进入boss房间通道通道时刻！")
                        agan_shown(self)
                        return "群岛地图默认路径规划 【👹】注：黑屏通道。"
                    count += 1
            time.sleep(self.ts)

    def _handle_unknown_map(self):
        return "未知地图类型，使用默认路径规划"


# ============================================【封装固定移动位置】======================================================
def hero_room_position_one(self, data, position_x, position_y, img=None, press_key=None, skill_direction=None):
    player_pos = DXFServer.extract_player_pos(data)
    target_pos = position_x, position_y
    DXFServer.move_towards_target(
        player_pos, target_pos,
        rise=self.rise,
        speed=self.speed
    )
    if skill_direction:
        DXFServer.vnc.key_press(skill_direction)
    if not press_key:
        press_key = dnf_skill_recognition.random_key_selector(img)
    DXFServer.vnc.key_press(press_key)


# ============================================【封装】=====================================================
# 定义循环最大次数，防止卡死
cycles = 8
left_wd = 280
right_wd = 600
skill_stop_time = 0.1
add_wd = 0
stop_ts = 0.08
move_to_target_and_stop_ts = 0.06

# 1. 定义方向键列表（将需要随机选择的键存入列表）
direction_keys = [
    keyboard.Left,  # 左方向键
    keyboard.Right,  # 右方向键
    keyboard.Up,  # 上方向键
    keyboard.Down  # 下方向键（注意：keyboard库中是Down，不是小写的down）
]


# ============================================*****=====================================================


def handle_first_room_logic(self, i_position):
    # 获取方向键控制函数并开始向右移动
    DXFServer.vnc.key_press(keyboard.Right)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Right)

    # 封装停止移动逻辑（闭包减少参数传递）
    def stop_moving():
        DXFServer.vnc.key_up(keyboard.Right)
        time.sleep(stop_ts)

    # 缓存关键参数（避免重复访问对象属性）
    rise = self.rise
    speed = self.speed

    while True:
        # 获取游戏窗口数据（合并数据提取，减少函数调用）
        data, img = DXFServer.get_win_image_info()
        door_pos = DXFServer.extract_door_pos(data)
        player_pos = DXFServer.extract_player_pos(data)
        if not player_pos:
            stop_moving()
            break
        if player_pos[0] > 700 + add_wd:
            stop_moving()
            press_direction(keyboard.Left, 0.3)
            continue
        if door_pos and door_pos:
            self.log(f"🚪 检测到门【出口】，坐标：{door_pos}")
            stop_moving()
            DXFServer.move_towards_target(
                player_pos, (door_pos[0], door_pos[1]),
                rise=rise,  # 使用缓存的参数
                speed=speed
            )
            break  # 移动后立即退出循环
        i_room = DXFServer.get_mini_map_img(self, img)
        if i_room != i_position:
            stop_moving()
            break
        time.sleep(self.ts)
    self.log("🔄 第一个房间逻辑结束")


def handle_right_down_room_logic(self, offset_x, offset_y, i_position, mini_wd=100, mini_ht=None):
    # 初始化移动状态和方向键控制（当前为向左移动逻辑）
    DXFServer.vnc.key_press(keyboard.Left)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Left)
    is_moving_left = False  # 新增：标记是否已经在左移

    def stop_moving():
        nonlocal is_moving_left
        """统一管理移动状态：停止当前移动并释放方向键"""
        self.log("✅ 已释放方向键")
        DXFServer.vnc.key_up(keyboard.Left)
        is_moving_left = False  # 重置标志
        time.sleep(stop_ts)

    def move_to_target_and_handle(target_pos, action_desc):
        """封装通用移动流程：停止当前移动→移动到目标→延迟"""
        stop_moving()
        if not player_pos:  # 依赖外部已获取的player_pos
            return False

        self.log(f"{action_desc} detected：{target_pos}")
        # 执行目标移动
        DXFServer.move_towards_target(
            player_pos, target_pos,
            rise=self.rise,
            speed=self.speed
        )
        time.sleep(move_to_target_and_stop_ts)
        return True

    # 计数循环次数，防止卡机
    i = 0
    target_door_pos = None
    try:
        while True:
            data, img = DXFServer.get_win_image_info()
            player_pos = DXFServer.extract_player_pos(data)
            i_room = DXFServer.get_mini_map_img(self, img)
            i += 1
            if i > cycles or i_room != i_position:
                stop_moving()
                break
            # 玩家坐标丢失处理
            if not player_pos:
                self.log("⚠️ 人物坐标丢失，疑似黑屏/掉线/中断")
                stop_moving()
                # 2. 随机选择一个方向键
                random_key = random.choice(direction_keys)
                press_direction(random_key, random.uniform(0.3, 1))
                continue

            # 1. 优先拾取掉落物
            goods_pos = DXFServer.extract_goods_pos(data)
            if goods_pos:
                if move_to_target_and_handle(goods_pos, "💰 掉落物"):
                    continue

            # 2. 其次攻击怪物
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                if move_to_target_and_handle(monster_pos, "👹 怪物"):
                    DXFServer.vnc.key_press(direction)
                    # 执行攻击操作
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    time.sleep(skill_stop_time)
                    continue

            # 3. 检测出口门（保留当前函数特有逻辑）
            door_pos, _ = DXFServer.extract_door_pos_value(
                data,
                sort_by_x=True,
                select_max=False  # 维持原门检测参数
            )
            if door_pos:
                if door_pos[0] < mini_wd:
                    # 应用当前房间特有的偏移量计算
                    target_door_pos = (door_pos[0] + offset_x, door_pos[1] + offset_y)
                # 满足目标门要求
                if mini_ht and door_pos[1] > mini_ht:
                    target_door_pos = door_pos
                if target_door_pos and move_to_target_and_handle(target_door_pos, "🚪 出口"):
                    # 再次校验是否过图
                    minimaps, img = DXFServer.get_mini_map(self)
                    _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                    if i_position == n_i_position:
                        continue
                    else:
                        break

            # 地图人物范围控制
            if player_pos[0] < left_wd:
                stop_moving()
                # 判断是否开门
                minimaps, img = DXFServer.get_mini_map(self)
                _, n_i_position, n = DXFServer.get_next_room_direction(minimaps)
                self.log(f"是否破门：{n} 是认证房间{i_position}当前房间{n_i_position}")
                if n and i_position == n_i_position:
                    move_time = random.uniform(0.3, 0.8)
                    press_direction(keyboard.Right, move_time)
                    continue
                if not n and i_position == n_i_position:
                    move_time = random.uniform(1.5, 2.5)
                    press_direction(keyboard.Right, move_time)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    continue

            # 4. 无目标时向左移动找门（修正方向描述）
            if not is_moving_left:
                DXFServer.vnc.key_press(keyboard.Left)
                time.sleep(random.uniform(0.05, 0.1))
                DXFServer.vnc.key_down(keyboard.Left)
                is_moving_left = True  # 标记为正在左移
                self.log("⬅️ 开始向左移动，寻找门")  # 修正原"向右移动"的描述错误
            time.sleep(self.ts)
    finally:
        self.log("🔄 已经结束一轮循环")


def handle_right_up_room_logic(self, offset_x, offset_y, i_position, door_num=False, door_x=100, door_y=None):
    # 初始化移动状态和方向键控制函数
    DXFServer.vnc.key_press(keyboard.Left)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Left)
    is_moving_left = False  # 新增：标记是否已经在左移

    def stop_moving():
        nonlocal is_moving_left
        """停止当前移动并释放方向键"""
        self.log("✅ 已释放方向键")
        DXFServer.vnc.key_up(keyboard.Left)
        is_moving_left = False  # 重置标志
        time.sleep(stop_ts)

    def move_to_target_and_handle(target_pos, action_desc):
        """移动到目标位置并执行后续操作"""
        stop_moving()
        player_pos = DXFServer.extract_player_pos(data)
        if not player_pos:
            return False

        self.log(f"{action_desc} detected！准备移动")
        DXFServer.move_towards_target(
            player_pos, target_pos,
            rise=self.rise,
            speed=self.speed
        )
        time.sleep(move_to_target_and_stop_ts)
        return True

    # 计数循环次数，防止卡机
    i = 0
    try:
        while True:
            data, img = DXFServer.get_win_image_info()
            player_pos = DXFServer.extract_player_pos(data)
            i_room = DXFServer.get_mini_map_img(self, img)
            i += 1
            if i > cycles or i_room != i_position:
                stop_moving()
                break

            # 检查玩家坐标是否有效
            if not player_pos:
                self.log("⚠️ 人物坐标丢失，疑似黑屏/掉线/中断")
                stop_moving()
                random_key = random.choice(direction_keys)
                press_direction(random_key, random.uniform(0.3, 1.5))
                continue

            # 1. 拾取金币优先
            goods_pos = DXFServer.extract_goods_pos(data)
            if goods_pos:
                if move_to_target_and_handle(goods_pos, "💰 掉落物"):
                    continue

            # 2. 攻击怪物
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                if move_to_target_and_handle(monster_pos, "👹 怪物"):
                    DXFServer.vnc.key_press(direction)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    time.sleep(skill_stop_time)
                    continue

            # 3. 如果没有怪物，开始检测门（出口）
            door_pos, door_number = DXFServer.extract_door_pos_value(data, sort_by_x=True, select_max=False)
            if door_num and door_pos and door_pos[0] > door_x:
                target_door_pos = door_pos
                if move_to_target_and_handle(target_door_pos, "🚪 出口"):
                    # 再次校验是否过图
                    minimaps, img = DXFServer.get_mini_map(self)
                    _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                    if i_position == n_i_position:
                        continue
                    else:
                        break
            elif door_pos and door_pos[0] < door_x:  # 入口条件 横轴
                if door_num and door_y and door_pos[1] < door_y:  # 满足条件就不用加偏移咯
                    offset_x = 0
                    offset_y = 0
                target_door_pos = (door_pos[0] + offset_x, door_pos[1] - offset_y)  # 应用偏移量
                if move_to_target_and_handle(target_door_pos, "🚪 出口"):
                    # 再次校验是否过图
                    minimaps, img = DXFServer.get_mini_map(self)
                    _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                    if i_position == n_i_position:
                        continue
                    else:
                        break
            if player_pos[0] < left_wd:
                stop_moving()
                # 判断是否开门
                minimaps, img = DXFServer.get_mini_map(self)
                _, n_i_position, n = DXFServer.get_next_room_direction(minimaps)
                self.log(f"是否破门：{n} 是认证房间{i_position}当前房间{n_i_position}")
                if n and i_position == n_i_position:
                    move_time = random.uniform(0.3, 0.8)
                    press_direction(keyboard.Right, move_time)
                    continue
                if not n and i_position == n_i_position:
                    move_time = random.uniform(1.5, 2.5)
                    press_direction(keyboard.Right, move_time)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    continue

            # 4. 没有怪物，也没有门，向左找门
            if not is_moving_left:
                DXFServer.vnc.key_press(keyboard.Left)
                time.sleep(random.uniform(0.05, 0.1))
                DXFServer.vnc.key_down(keyboard.Left)
                is_moving_left = True  # 标记为正在左移
                self.log("⬅️ 开始向左移动，寻找门")  # 修正方向描述
            time.sleep(self.ts)
    finally:
        self.log("🔄 已经结束一轮循环")


def handle_right_up_room_logic2(self, offset_x, offset_y, i_position, y_ht, w_wd=100):
    # 初始化移动状态和方向键控制函数
    DXFServer.vnc.key_press(keyboard.Left)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Left)
    is_moving_left = False  # 新增：标记是否已经在左移

    def stop_moving():
        nonlocal is_moving_left
        """停止当前移动并释放方向键"""
        self.log("✅ 已释放方向键")
        DXFServer.vnc.key_up(keyboard.Left)
        is_moving_left = False  # 重置标志
        time.sleep(stop_ts)

    def move_to_target_and_handle(target_pos, action_desc):
        """移动到目标位置并执行后续操作"""
        stop_moving()
        player_pos = DXFServer.extract_player_pos(data)
        if not player_pos:
            return False

        self.log(f"{action_desc} detected！准备移动")
        DXFServer.move_towards_target(
            player_pos, target_pos,
            rise=self.rise,
            speed=self.speed
        )
        time.sleep(move_to_target_and_stop_ts)
        return True

    # 计数循环次数，防止卡机
    i = 0
    try:
        while True:
            data, img = DXFServer.get_win_image_info()
            player_pos = DXFServer.extract_player_pos(data)
            i_room = DXFServer.get_mini_map_img(self, img)
            i += 1
            if i > cycles or i_room != i_position:
                stop_moving()
                break
            # 检查玩家坐标是否有效
            if not player_pos:
                self.log("⚠️ 人物坐标丢失，疑似黑屏/掉线/中断")
                stop_moving()
                random_key = random.choice(direction_keys)
                press_direction(random_key, random.uniform(0.3, 1.5))
                continue

            # 1. 拾取金币优先
            goods_pos = DXFServer.extract_goods_pos(data)
            if goods_pos:
                if move_to_target_and_handle(goods_pos, "💰 掉落物"):
                    continue

            # 2. 攻击怪物
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                if move_to_target_and_handle(monster_pos, "👹 怪物"):
                    DXFServer.vnc.key_press(direction)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    time.sleep(skill_stop_time)
                    continue

            # 3. 如果没有怪物，开始检测门（出口）
            door_pos, _ = DXFServer.extract_door_pos_value(data, sort_by_x=True, select_max=False)
            if door_pos and door_pos[0] < w_wd and door_pos[1] > y_ht:  # 右侧上门判断条件
                target_door_pos = (door_pos[0] + offset_x, door_pos[1] - offset_y)  # 应用偏移量
                if move_to_target_and_handle(target_door_pos, "🚪 出口"):
                    # 再次校验是否过图
                    minimaps, img = DXFServer.get_mini_map(self)
                    _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                    if i_position == n_i_position:
                        continue
                    else:
                        break
            if player_pos[0] < left_wd:
                stop_moving()
                # 判断是否开门
                minimaps, img = DXFServer.get_mini_map(self)
                _, n_i_position, n = DXFServer.get_next_room_direction(minimaps)
                self.log(f"是否破门：{n} 是认证房间{i_position}当前房间{n_i_position}")
                if n and i_position == n_i_position:
                    move_time = random.uniform(0.3, 0.8)
                    press_direction(keyboard.Right, move_time)
                    continue
                if not n and i_position == n_i_position:
                    move_time = random.uniform(1.5, 2.5)
                    press_direction(keyboard.Right, move_time)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    continue

            # 4. 没有怪物，也没有门，向左找门
            if not is_moving_left:
                DXFServer.vnc.key_press(keyboard.Left)
                time.sleep(random.uniform(0.05, 0.1))
                DXFServer.vnc.key_down(keyboard.Left)
                is_moving_left = True  # 标记为正在左移
                self.log("⬅️ 开始向左移动，寻找门")  # 修正方向描述
            time.sleep(self.ts)

    finally:
        self.log("🔄 已经结束一轮循环")


# door_y 是否需要走偏移，如果传None 就直接默认是出口门
def handle_left_down_room_logic(self, offset_x, offset_y, i_position, door_y=None, door_x=600):
    # 初始化移动状态和方向键控制函数（当前逻辑为向右移动）
    DXFServer.vnc.key_press(keyboard.Right)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Right)
    is_moving_right = False  # 新增：标记是否已经在左移

    def stop_moving():
        nonlocal is_moving_right
        """停止当前移动并释放方向键（统一管理移动状态）"""
        self.log("✅ 已释放方向键")
        DXFServer.vnc.key_up(keyboard.Right)
        is_moving_right = False  # 重置标志
        time.sleep(stop_ts)

    def move_to_target_and_handle(target_pos, action_desc):
        """封装通用移动逻辑：停止当前移动→移动到目标→延迟"""
        # 确保玩家坐标有效
        stop_moving()
        if not player_pos:
            return False
        # 移动前先停止当前移动
        self.log(f"{action_desc} detected：{target_pos}")
        # 执行移动
        DXFServer.move_towards_target(
            player_pos, target_pos,
            rise=self.rise,
            speed=self.speed
        )
        time.sleep(move_to_target_and_stop_ts)
        return True

    # 计数循环次数，防止卡机
    i = 0
    try:
        while True:
            data, img = DXFServer.get_win_image_info()
            player_pos = DXFServer.extract_player_pos(data)
            i_room = DXFServer.get_mini_map_img(self, img)
            i += 1
            if i > cycles or i_room != i_position:
                stop_moving()
                break

            # 玩家坐标丢失处理
            if not player_pos:
                self.log("⚠️ 人物坐标丢失，疑似黑屏/掉线/中断")
                stop_moving()
                random_key = random.choice(direction_keys)
                press_direction(random_key, random.uniform(0.3, 1.5))
                continue

            # 1. 优先拾取掉落物
            goods_pos = DXFServer.extract_goods_pos(data)
            if goods_pos:
                if move_to_target_and_handle(goods_pos, "💰 掉落物"):
                    continue

            # 2. 其次攻击怪物
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                if move_to_target_and_handle(monster_pos, "👹 怪物"):
                    DXFServer.vnc.key_press(direction)
                    # 攻击逻辑：随机按键
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    time.sleep(skill_stop_time)
                    continue

            # 3. 检测到门且满足条件（处理偏移量）
            door_pos, _ = DXFServer.extract_door_pos_value(
                data,
                sort_by_x=True,
                select_max=True
            )
            if door_pos and door_pos[0] > door_x:
                # 如果传的door_y 说明需要判断门的纵轴距离 走偏移
                if door_y and door_pos[1] < door_y:
                    # 门位置应用偏移量（当前函数特有逻辑）
                    target_door_pos = (door_pos[0] - offset_x, door_pos[1] + offset_y)
                    if move_to_target_and_handle(target_door_pos, "🚪 出口（已应用偏移）"):
                        # 再次校验是否过图
                        minimaps, img = DXFServer.get_mini_map(self)
                        _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                        if i_position == n_i_position:
                            continue
                        else:
                            break
                else:
                    target_door_pos = door_pos
                    if move_to_target_and_handle(target_door_pos, "🚪 出口（已应用偏移）"):
                        # 再次校验是否过图
                        minimaps, img = DXFServer.get_mini_map(self)
                        _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                        if i_position == n_i_position:
                            continue
                        else:
                            break
            if player_pos[0] > door_x + add_wd:
                stop_moving()
                # 判断是否开门
                minimaps, img = DXFServer.get_mini_map(self)
                _, n_i_position, n = DXFServer.get_next_room_direction(minimaps)
                self.log(f"是否破门：{n} 是认证房间{i_position}当前房间{n_i_position}")
                if n and i_position == n_i_position:
                    move_time = random.uniform(0.3, 0.8)
                    press_direction(keyboard.Left, move_time)
                    continue
                if not n and i_position == n_i_position:
                    move_time = random.uniform(1.5, 2.5)
                    press_direction(keyboard.Left, move_time)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    continue

            # 4. 无目标时向右移动找门（维持原移动逻辑）
            if not is_moving_right:
                DXFServer.vnc.key_press(keyboard.Right)
                time.sleep(random.uniform(0.05, 0.1))
                DXFServer.vnc.key_down(keyboard.Right)
                is_moving_right = True  # 标记为正在左移
                self.log("➡️ 开始向右移动，寻找门")
            time.sleep(self.ts)
    finally:
        self.log("🔄 已经结束一轮循环")


def handle_left_up_room_logic(self, offset_x, offset_y, i_position, door_y=None, target_x=700, target_out=None):
    # 初始化移动状态和方向键控制（当前为向右移动逻辑）
    DXFServer.vnc.key_press(keyboard.Right)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Right)
    is_moving_right = False  # 新增：标记是否已经在左移

    def stop_moving():
        nonlocal is_moving_right
        """统一管理移动状态：停止当前移动并释放方向键"""
        self.log("✅ 已释放方向键")
        DXFServer.vnc.key_up(keyboard.Right)
        is_moving_right = False  # 重置标志
        time.sleep(stop_ts)

    def move_to_target_and_handle(target_pos, action_desc):
        """封装通用移动流程：停止当前移动→移动到目标→延迟"""
        stop_moving()
        if not player_pos:  # 依赖外部已获取的player_pos
            return False

        self.log(f"{action_desc} detected：{target_pos}")
        # 执行目标移动
        DXFServer.move_towards_target(
            player_pos, target_pos,
            rise=self.rise,
            speed=self.speed
        )
        time.sleep(move_to_target_and_stop_ts)
        return True

    # 计数循环次数，防止卡机
    i = 0
    try:
        while True:
            data, img = DXFServer.get_win_image_info()
            player_pos = DXFServer.extract_player_pos(data)
            i_room = DXFServer.get_mini_map_img(self, img)
            i += 1
            if i > cycles or i_room != i_position:
                stop_moving()
                break
            # 玩家坐标丢失处理
            if not player_pos:
                # self.log("⚠️ 人物坐标丢失，疑似黑屏/掉线/中断")
                stop_moving()
                random_key = random.choice(direction_keys)
                press_direction(random_key, random.uniform(0.3, 1.5))
                continue

            # 1. 优先拾取掉落物
            goods_pos = DXFServer.extract_goods_pos(data)
            if goods_pos:
                if move_to_target_and_handle(goods_pos, "💰 掉落物"):
                    continue

            # 2. 其次攻击怪物
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                if move_to_target_and_handle(monster_pos, "👹 怪物"):
                    DXFServer.vnc.key_press(direction)
                    # 执行攻击操作
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    time.sleep(skill_stop_time)
                    continue

            # 3. 检测出口门
            door_pos, _ = DXFServer.extract_door_pos_value(
                data,
                sort_by_x=True,
                select_max=True  # 获取最右侧的门
            )
            if door_pos and door_pos[0] > target_x:
                # 如果传的door_y 说明需要判断门的纵轴距离
                if door_y and door_pos[1] > door_y:
                    # 应用当前房间特有的偏移量计算
                    target_door_pos = (door_pos[0] - offset_x, door_pos[1] - offset_y)
                    if move_to_target_and_handle(target_door_pos, "🚪 出口"):
                        # 再次校验是否过图
                        minimaps, img = DXFServer.get_mini_map(self)
                        _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                        if i_position == n_i_position:
                            continue
                        else:
                            break
            if door_pos and target_out and door_pos[0] < target_out:
                target_door_pos = door_pos
                if move_to_target_and_handle(target_door_pos, "🚪 出口"):
                    # 再次校验是否过图
                    minimaps, img = DXFServer.get_mini_map(self)
                    _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                    if i_position == n_i_position:
                        continue
                    else:
                        break
            # 防止玩家跑出右边界
            if player_pos[0] > right_wd + add_wd:
                stop_moving()
                # 判断是否开门
                minimaps, img = DXFServer.get_mini_map(self)
                _, n_i_position, n = DXFServer.get_next_room_direction(minimaps)
                self.log(f"是否破门：{n} 是认证房间{i_position}当前房间{n_i_position}")
                if n and i_position == n_i_position:
                    move_time = random.uniform(0.3, 0.8)
                    press_direction(keyboard.Left, move_time)
                    continue
                if not n and i_position == n_i_position:
                    move_time = random.uniform(1.5, 2.5)
                    press_direction(keyboard.Left, move_time)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    continue
            # 4. 无目标时向右移动找门
            if not is_moving_right:
                DXFServer.vnc.key_press(keyboard.Right)
                time.sleep(random.uniform(0.05, 0.1))
                DXFServer.vnc.key_down(keyboard.Right)
                is_moving_right = True  # 标记为正在左移
                self.log("➡️ 开始向右移动，寻找门")
            time.sleep(self.ts)
    finally:
        self.log("🔄 左上房间逻辑结束")


def handle_left_room_logic(self, i_position, door_x=100, left_room_wd=200):
    # 初始化移动状态和方向键控制函数
    DXFServer.vnc.key_press(keyboard.Left)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Left)
    is_moving_left = False  # 新增：标记是否已经在左移

    def stop_moving():
        nonlocal is_moving_left
        """停止当前移动并释放方向键"""
        self.log("✅ 已释放方向键")
        DXFServer.vnc.key_up(keyboard.Left)
        is_moving_left = False  # 重置标志
        time.sleep(stop_ts)

    def move_to_target_and_handle(target_pos, action_desc):
        """移动到目标位置并执行后续操作"""
        stop_moving()
        player_pos = DXFServer.extract_player_pos(data)
        if not player_pos:
            return False

        self.log(f"{action_desc} detected！准备移动")
        DXFServer.move_towards_target(
            player_pos, target_pos,
            rise=self.rise,
            speed=self.speed
        )
        time.sleep(move_to_target_and_stop_ts)
        return True

    # 计数循环次数，防止卡机
    i = 0
    try:
        while True:
            data, img = DXFServer.get_win_image_info()
            player_pos = DXFServer.extract_player_pos(data)
            i_room = DXFServer.get_mini_map_img(self, img)
            i += 1
            if i > cycles or i_room != i_position:
                stop_moving()
                break
            # 检查玩家坐标是否有效
            if not player_pos:
                self.log("⚠️ 人物坐标丢失，疑似黑屏/掉线/中断")
                stop_moving()
                random_key = random.choice(direction_keys)
                press_direction(random_key, random.uniform(0.3, 1.5))
                continue

            # 1. 拾取金币优先
            goods_pos = DXFServer.extract_goods_pos(data)
            if goods_pos:
                if move_to_target_and_handle(goods_pos, "💰 掉落物"):
                    time.sleep(skill_stop_time)
                    continue

            # 2. 攻击怪物
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                if move_to_target_and_handle(monster_pos, "👹 怪物"):
                    DXFServer.vnc.key_press(direction)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    time.sleep(skill_stop_time)
                    continue
            # 3. 如果没有怪物，开始检测门（出口）
            door_pos = DXFServer.extract_door_pos(data)
            if door_pos and door_pos[0] < door_x:  # 左侧门判断条件
                if move_to_target_and_handle((door_pos[0], door_pos[1]), "🚪 出口"):
                    # 再次校验是否过图
                    minimaps, img = DXFServer.get_mini_map(self)
                    _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                    if i_position == n_i_position:
                        continue
                    else:
                        break
            if player_pos[0] < left_room_wd:
                stop_moving()
                # 判断是否开门
                minimaps, img = DXFServer.get_mini_map(self)
                _, n_i_position, n = DXFServer.get_next_room_direction(minimaps)
                self.log(f"是否破门：{n} 是认证房间{i_position}当前房间{n_i_position}")
                if n and i_position == n_i_position:
                    move_time = random.uniform(0.3, 0.8)
                    press_direction(keyboard.Right, move_time)
                    continue
                if not n and i_position == n_i_position:
                    move_time = random.uniform(1.5, 2.5)
                    press_direction(keyboard.Right, move_time)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    continue
            # 5. 没有怪物，也没有门，向左找门
            if not is_moving_left:
                DXFServer.vnc.key_press(keyboard.Left)
                time.sleep(random.uniform(0.05, 0.1))
                DXFServer.vnc.key_down(keyboard.Left)
                is_moving_left = True  # 标记为正在左移
                self.log("⬅️ 开始向左移动，寻找门")  # 修正方向描述
            time.sleep(self.ts)
    finally:
        self.log("🔄 已经结束一轮循环")


def handle_right_room_logic(self, i_position, door_len=700):
    # 初始化移动状态和方向键控制函数
    DXFServer.vnc.key_press(keyboard.Right)
    time.sleep(random.uniform(0.05, 0.1))
    DXFServer.vnc.key_down(keyboard.Right)
    is_moving_right = False  # 新增：标记是否已经在左移

    def stop_moving():
        nonlocal is_moving_right
        """停止当前移动并释放方向键"""
        self.log("✅ 已释放方向键")
        DXFServer.vnc.key_up(keyboard.Right)
        is_moving_right = False  # 重置标志
        time.sleep(stop_ts)

    def move_to_target_and_handle(target_pos, action_desc):
        """移动到目标位置并执行后续操作"""
        stop_moving()
        player_pos = DXFServer.extract_player_pos(data)
        if not player_pos:
            return False

        self.log(f"{action_desc} detected！准备移动")
        DXFServer.move_towards_target(
            player_pos, target_pos,
            rise=self.rise,
            speed=self.speed
        )
        time.sleep(move_to_target_and_stop_ts)
        return True

    # 计数循环次数，防止卡机
    i = 0
    try:
        while True:
            data, img = DXFServer.get_win_image_info()
            player_pos = DXFServer.extract_player_pos(data)
            i_room = DXFServer.get_mini_map_img(self, img)
            i += 1
            if i > cycles or i_room != i_position:
                stop_moving()
                break

            # 检查玩家坐标是否有效
            if not player_pos:
                # self.log("⚠️ 人物坐标丢失，疑似黑屏/掉线/中断")
                stop_moving()
                random_key = random.choice(direction_keys)
                press_direction(random_key, random.uniform(0.3, 1.5))
                continue

            # 1. 拾取金币优先
            goods_pos = DXFServer.extract_goods_pos(data)
            if goods_pos:
                if move_to_target_and_handle(goods_pos, "💰 掉落物"):
                    continue

            # 2. 攻击怪物
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                if move_to_target_and_handle(monster_pos, "👹 怪物"):
                    DXFServer.vnc.key_press(direction)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    time.sleep(skill_stop_time)
                    continue

            # 3. 如果没有怪物，开始检测门（出口）
            door_pos = DXFServer.extract_door_pos(data)
            if door_pos and door_pos[0] > door_len:
                if move_to_target_and_handle((door_pos[0], door_pos[1]), "🚪 出口"):
                    # 再次校验是否过图
                    minimaps, img = DXFServer.get_mini_map(self)
                    _, n_i_position, _ = DXFServer.get_next_room_direction(minimaps)
                    if i_position == n_i_position:
                        continue
                    else:
                        break
            if player_pos[0] > door_len + add_wd:
                stop_moving()
                # 判断是否开门
                minimaps, img = DXFServer.get_mini_map(self)
                _, n_i_position, n = DXFServer.get_next_room_direction(minimaps)
                self.log(f"是否破门：{n} 是认证房间{i_position}当前房间{n_i_position}")
                if n and i_position == n_i_position:
                    move_time = random.uniform(0.3, 0.8)
                    press_direction(keyboard.Left, move_time)
                    continue
                if not n and i_position == n_i_position:
                    move_time = random.uniform(1.5, 2.5)
                    press_direction(keyboard.Left, move_time)
                    press_key = dnf_skill_recognition.random_key_selector(img)
                    DXFServer.vnc.key_press(press_key)
                    continue

            # 5. 没有怪物，也没有门，向右找门
            if not is_moving_right:
                DXFServer.vnc.key_press(keyboard.Right)
                time.sleep(random.uniform(0.05, 0.1))
                DXFServer.vnc.key_down(keyboard.Right)
                is_moving_right = True  # 标记为正在左移
                self.log("➡️ 开始向右移动，寻找门")
            time.sleep(self.ts)
    finally:
        self.log("🔄 已经结束一轮循环")


def press_direction(pre_key, ts=0.5):
    """
    模拟按下指定方向键并保持一段时间

    参数:
    direction (str): 方向键名称，支持 keyboard.Up, keyboard.Down, keyboard.Left, keyboard.Right
    duration (float): 按键持续时间，单位为秒，默认0.5秒
    """
    valid_directions = [keyboard.Up, keyboard.Down, keyboard.Left, keyboard.Right]
    if pre_key not in valid_directions:
        raise ValueError(f"方向参数无效，必须是 {valid_directions} 中的一个")
    DXFServer.vnc.key_press(pre_key)  # 按下键
    DXFServer.vnc.key_down(pre_key)
    time.sleep(ts)
    DXFServer.vnc.key_up(pre_key)
    time.sleep(stop_ts)


def get_found_position(maps, param):
    return next(
        (
            (item['found'],
             tuple(pos // 18 for pos in item['position'])
             if item['position'] else None)  # 处理空position的情况
            for item in maps
            if item['template'].endswith(param)
        ),
        (False, None)
    )


def get_player_position_down_move_left(self, x_ht=110):
    data, img = DXFServer.get_win_image_info()
    player_pos = DXFServer.extract_player_pos(data)
    if not player_pos:
        return None
    if player_pos[1] + self.rise < x_ht:
        press_direction(keyboard.Down, 0.3)


def get_player_position_up_move_left(self, x_ht=300):
    data, img = DXFServer.get_win_image_info()
    player_pos = DXFServer.extract_player_pos(data)
    if not player_pos:
        return None
    if player_pos[1] + self.rise > x_ht:
        press_direction(keyboard.Up, 0.3)


def get_player_position_down_move_right(self, x_ht=690):
    data, img = DXFServer.get_win_image_info()
    player_pos = DXFServer.extract_player_pos(data)
    if not player_pos:
        return None
    if player_pos[1] + self.rise < x_ht:
        press_direction(keyboard.Down, 0.3)


def get_player_position_up_move(self, y_height=None, top_height=None, t_ms=0.5):
    data, img = DXFServer.get_win_image_info()
    player_pos = DXFServer.extract_player_pos(data)
    if not player_pos:
        return None
    food_pos = player_pos[1] + self.rise
    # self.log(f"玩家脚点：{food_pos}，身高：{self.rise} 限顶高度：{top_height}，限底高度：{y_height}")
    if food_pos > y_height:
        press_direction(keyboard.Up, t_ms)
    if top_height and food_pos < top_height:
        press_direction(keyboard.Down, 0.3)


def get_player_position_left_move(self, x_wd=110):
    data, img = DXFServer.get_win_image_info()
    player_pos = DXFServer.extract_player_pos(data)
    if not player_pos:
        return None
    if player_pos[0] < x_wd:
        press_direction(keyboard.Left, 0.3)


def get_player_position_right_move(self, x_wd=110, w_ht=None, top_height=None):
    data, img = DXFServer.get_win_image_info()
    player_pos = DXFServer.extract_player_pos(data)
    if not player_pos:
        return None
    if player_pos[0] < x_wd:
        press_direction(keyboard.Right, random.uniform(0.5, 1.5))
    if player_pos[1] + self.rise > w_ht:
        press_direction(keyboard.Up, 0.3)
    if player_pos[1] + self.rise < top_height:
        press_direction(keyboard.Down, 0.3)


def brand_shown(planner):
    """翻牌显示"""
    temp_brand = planner.valid_templates.get('./model/brand.png')
    data, image = DXFServer.get_win_image_info()
    box = (315, 23, 74, 16)
    img = image[box[1]:box[1] + box[3], box[0]:box[0] + box[2]]
    stu, _ = DXFServer.template_picture(img, temp_brand, 0.75, "brand")
    if stu:
        time.sleep(1)
        planner.log("翻牌通过", "SUCCESS")
        DXFServer.vnc.key_press(keyboard.Esc)
        return True
    return False


def human_press(key, times=1):
    """模拟人类按键，带随机间隔"""
    for i in range(times):
        DXFServer.vnc.key_press(key)  # 已包含按下和弹起
        # 非最后一次按键添加随机间隔
        if i < times - 1:
            interval = random.uniform(0.08, 0.3)
            # 10%概率延长间隔，模拟犹豫
            if random.random() < 0.1:
                interval *= random.uniform(1.5, 3)
            time.sleep(interval)


def agan_shown(planner):
    temp_again = planner.valid_templates.get('./model/again.png')
    temp_shop = planner.valid_templates.get('./model/shop.png')
    temp_yao_qi_ju_xian_zx = planner.valid_templates.get('./model/yao_qi_ju_xian_zx.png')
    temp_shan_shan_mi = planner.valid_templates.get('./model/shan_shan_mi.png')
    while True:
        image = DXFServer.window_capture_win()
        box = (632, 47, 80, 18)
        img = image[box[1]:box[1] + box[3], box[0]:box[0] + box[2]]  # 使用裁剪区域裁剪图像
        stu, _ = DXFServer.template_picture(img, temp_again, 0.75, "again")
        if stu:
            planner.log('【再次挑战已浮现】')
            # 神秘商店
            box = (159, 395, 65, 18)
            img = image[box[1]:box[1] + box[3], box[0]:box[0] + box[2]]  # 使用裁剪区域裁剪图像
            stu, _ = DXFServer.template_picture(img, temp_shop, 0.75, "shop")
            if stu:
                planner.log('【神秘商店已浮现】')
                while True:
                    data, image = DXFServer.get_win_image_info()
                    box = (12, 449, 58, 28)
                    img = image[box[1]:box[1] + box[3], box[0]:box[0] + box[2]]  # 使用裁剪区域裁剪图像
                    stu_yao_ju, pos_yao_ju = DXFServer.template_picture(img, temp_yao_qi_ju_xian_zx, 0.75, "yao_qi_ju_xian_zx")
                    stu_shan_shan, pos_shan_shan = DXFServer.template_picture(img, temp_shan_shan_mi, 0.75, "shan_shan_mi")
                    if stu_yao_ju:
                        use_pos = pos_yao_ju
                    elif stu_shan_shan:
                        use_pos = pos_shan_shan
                    else:
                        planner.log('🎯 购买完成！', "SUCCESS")
                        break
                    if use_pos:
                        time.sleep(1)
                        DXFServer.mouse_to_click(12, 449, use_pos[0], use_pos[1])
                        time.sleep(1.4)
                        DXFServer.vnc.key_press(keyboard.Space)
                    time.sleep(1.5)
            planner.log('【关闭黑商】防止抖动遮罩再次挑战标识！')
            DXFServer.vnc.key_press(keyboard.Esc)
            time.sleep(0.5)
            planner.log("一键拾取【v】、再次挑战【F10】")
            DXFServer.vnc.key_press(keyboard.V)
            human_press(keyboard.X, 3)
            DXFServer.vnc.key_press(keyboard.F10)
            break
        else:
            planner.log("未识别再次挑战标志：停止2.5秒")
            time.sleep(2.5)


DEFAULT_RESULT = {'name': None, 'position': None}


def get_found_info(data_list):
    """
    提取列表中第一个found为True的对象，返回其对应中文名称和position值
    """
    try:
        item = next(filter(lambda x: x.get('found') and x.get('template') in VALID_TEMPLATES, data_list))
    except StopIteration:
        return DEFAULT_RESULT

    position = item.get('position')
    if not isinstance(position, (list, tuple)) or len(position) < 2:
        return DEFAULT_RESULT

    try:
        return {
            'name': TEMPLATE_MAP[item['template']],
            'position': (position[0] // 18, position[1] // 18)
        }
    except (KeyError, TypeError, ZeroDivisionError):
        return DEFAULT_RESULT


def get_boos_room_status(planner, room, desc):
    direct_move = keyboard.Right
    planner.log(f"进阶【boss房间检测】。。。大招是否秒！👹")
    time.sleep(random.uniform(2, 4))
    while True:
        minimaps, img = DXFServer.get_mini_map(planner)
        _, i_position, _ = DXFServer.get_next_room_direction(minimaps)
        data = DXFServer.get_image_info(img)
        if i_position == room:
            planner.log(f"处于boos房间中。。。{i_position}")
            monster_pos, direction = DXFServer.extract_monster_pos(data)
            if monster_pos:
                planner.log(f"抓 boos 👹 怪物")
                hero_room_position_one(planner, data, monster_pos[0], monster_pos[1], img)
            else:
                planner.log(f"处于boss房间却未找到boss身影【左右移动:停3秒】 👹 怪物")
                time.sleep(1)
                direct_move = keyboard.Left if direct_move == keyboard.Right else keyboard.Right
                press_direction(direct_move, 0.8)
                time.sleep(1)
                press_key = dnf_skill_recognition.random_key_selector(img)
                DXFServer.vnc.key_press(press_key)
        else:
            # 检测是否翻拍、再次挑战是否浮现、pl是否清完、是否异常返回城镇。
            if brand_shown(planner):
                agan_shown(planner)
                return desc
        time.sleep(2)

def link_jl():
    DXFServer.mouse_to_click(0, 0, 632+random.uniform(0, 3), 542+random.uniform(0, 3))
    time.sleep(1.3)
    DXFServer.mouse_to_click(0, 0, 343 + random.uniform(0, 6), 502 + random.uniform(0, 4))
    time.sleep(1.6)
    DXFServer.mouse_to_click(0, 0, 354 + random.uniform(0, 8), 326 + random.uniform(0, 5))
    time.sleep(1.3)
    DXFServer.mouse_to_click(0, 0, 343 + random.uniform(0, 6), 502 + random.uniform(0, 4))


if __name__ == '__main__':
    from gui_app import ModernDNFBotGUI
    import tkinter as tk
    a = ModernDNFBotGUI(tk.Tk())
    # # 创建路径规划器实例
    planner = GamePathPlanner()
    # planner.mini_map_templates=a.mini_map_templates
    # planner.mini_map_temp_types=a.mini_map_temp_types
    DXFServer.vnc.connect()
    # planner.rise = 155
    # planner.speed = 108.0
    # img = DXFServer.window_capture_win()
    # planner.set_i_position((1, 0))
    # planner.set_boss_position((6, 0))  # 假设BOSS位置为(108, 72)
    # planner.map_position = (3, 0)
    # planner.map_type = '群岛'
    # planner.plan_path()
    # a = False
    # if not a:
    #     print(1)

    DXFServer.mouse_to_click(0, 0, 632+random.uniform(0, 3), 542+random.uniform(0, 3))
    time.sleep(1.3)
    DXFServer.mouse_to_click(0, 0, 343 + random.uniform(0, 6), 502 + random.uniform(0, 4))
    time.sleep(1.6)
    DXFServer.mouse_to_click(0, 0, 354 + random.uniform(0, 8), 326 + random.uniform(0, 5))
    time.sleep(1.3)
    DXFServer.mouse_to_click(0, 0, 343 + random.uniform(0, 6), 502 + random.uniform(0, 4))

